package com.jl.card.tracer;

import java.util.concurrent.ArrayBlockingQueue;

import opencard.core.terminal.CommandAPDU;
import opencard.core.terminal.ResponseAPDU;
import opencard.core.terminal.SlotChannel;

import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;

import com.jl.scr.CMD;
import com.jl.util.HexUtil;

/**
 * tracer this apdu
 * 
 * @author LuHongjun
 */
public final class EditorTracer implements ISCRTracer {
	/**
	 * 
	 */
	private final IAppendAble scrEditor;
	private final ArrayBlockingQueue<String> array = new ArrayBlockingQueue<String>(
			1024 * 10);

	/**
	 * @param scrEditor
	 */
	public EditorTracer(IAppendAble scrEditor) {
		this.scrEditor = scrEditor;
		new Thread(new Take()).start();
	}

	private CMD cmd = null;

	@Override
	public void traceCommandAPDU(SlotChannel arg0, CommandAPDU apdu) {
		cmd = new CMD(apdu);
	}

	@Override
	public void traceResponseAPDU(SlotChannel arg0, ResponseAPDU apdu) {
		cmd.setSW(HexUtil.toHex(apdu.sw(), 2));
		cmd.setExcept(HexUtil.toHexString(apdu.data()));
		appendString(cmd.toString());
	}

	@Override
	public void tracerString(String info) {
		appendString(info);
	}

	private void appendString(final String str) {
		try {
			array.put(str);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private class Take implements Runnable {
		private Display display = null;

		@Override
		public void run() {
			while (true) {
				try {
					final String val = array.take();
					if (display == null) {
						display = ((IEditorPart) scrEditor).getSite()
								.getShell().getDisplay();
					}
					display.syncExec(new Runnable() {
						@Override
						public void run() {
							scrEditor.append(val);
						}
					});
				} catch (InterruptedException e) {
					e.printStackTrace();
					return;
				}
			}
		}
	}
}